import { generateUUID } from "./utils";

export interface WorkerMessage extends Message {
  UUID: string;
}

export default class Worker {
  worker;
  resolveMap = new Map();

  constructor(private path) {
    this.worker = new window.Worker(this.path, { type: "module" });

    this.worker.onmessage = (event) => {
      const resolve = this.resolveMap.get(event.data.UUID);
      if (resolve) {        
        resolve(event.data.data);
        this.resolveMap.delete(event.data.UUID);
      }
    };

    window.addEventListener("beforeunload", () => this.worker.terminate());
  }

  onMessage(fn: (event) => void) {
    this.worker.addEventListener("message", fn);
  }

  postMessage(message: Message): Promise<unknown> {
    const workerMessage = message as WorkerMessage
    workerMessage.UUID = generateUUID()

    this.worker.postMessage(message)

    return new Promise(resolve => {
      this.resolveMap.set(workerMessage.UUID, resolve)
    })
  }

  terminate() {
    this.worker.terminate();
  }
}
